﻿namespace MefContrib.Models.Provider.Tests
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Primitives;
    using NUnit.Framework;

    [TestFixture]
    public class TypeExtensionsTests
    {
        [Test]
        public void IsEnumerableShouldBeTrueForICollection()
        {
            Assert.IsTrue(typeof(ICollection).IsEnumerable());
        }

        [Test]
        public void IsEnumerableShouldBeTrueForICollectionOfT()
        {
            Assert.IsTrue(typeof(ICollection<>).IsEnumerable());
        }

        [Test]
        public void IsEnumerableShouldBeTrueForIEnumerable()
        {
            Assert.IsTrue(typeof(IEnumerable).IsEnumerable());
        }

        [Test]
        public void IsEnumerableShouldBeTrueForIEnumerableOfT()
        {
            Assert.IsTrue(typeof(IEnumerable<>).IsEnumerable());
        }

        [Test]
        public void IsEnumerableShouldExtractInterfaceFromTypeAndReturnTrue()
        {
            Assert.IsTrue(typeof(FakeEnumerableType).IsEnumerable());
        }

        [Test]
        public void IsEnumerableShouldReturnFalseForNonEnumerableInterface()
        {
            Assert.IsFalse(typeof(object).IsEnumerable());
        }

        [Test]
        public void IsEnumerableShouldReturnFalseForString()
        {
            Assert.IsFalse(typeof(string).IsEnumerable());
        }

        /*
        [Test]
        public void IsLazyTypeShouldReturnTrueForExport()
        {
            Assert.IsTrue(typeof(Export).IsLazyType());
        }
         * */

        [Test]
        public void IsLazyTypeShouldReturnTrueForLazyOfT()
        {
            Assert.IsTrue(typeof(Lazy<>).IsLazyType());
        }

        [Test]
        public void IsLazyTypeShouldReturnTrueForLazyOfTTMetaview()
        {
            Assert.IsTrue(typeof(Lazy<,>).IsLazyType());
        }

        /*
        [Test]
        public void IsLazyTypeShouldReturnTrueForExportCollection()
        {
            Assert.IsTrue(typeof(ExportCollection).IsLazyType());
        }

        [Test]
        public void IsLazyTypeShouldReturnTrueForExportCollectionOfT()
        {
            Assert.IsTrue(typeof(ExportCollection<>).IsLazyType());
        }

        [Test]
        public void IsLazyTypeShouldReturnTrueForExportCollectionOfTTMetaview()
        {
            Assert.IsTrue(typeof(ExportCollection<,>).IsLazyType());
        }
         */

        [Test]
        public void IsLazyTypeShouldReturnFalseForNonLazyType()
        {
            Assert.IsFalse(typeof(object).IsLazyType());
        }

        [Test]
        public void IsLazyTypeShouldReturnTrueForLazySubTypes()
        {
            Assert.IsTrue(typeof(FakeEnumerableType).IsLazyType());
        }
    }

    public class FakeEnumerableType : Lazy<object>, IEnumerable, IComparable
    {
        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public int CompareTo(object obj)
        {
            throw new NotImplementedException();
        }
    }
}